home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d8
/
pdriver5.arc
/
PKTADDR.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-12-17
|
6KB
|
327 lines
; Russell Nelson, Clarkson University. September 14, 1989
; Copyright, 1989, Russell Nelson
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, version 1.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
include defs.asm
code segment byte public
assume cs:code, ds:code
org 80h
phd_dioa label byte
org 100h
start:
jmp start_1
their_isr dd ?
packet_int_no db ?,?
ether_bdcst db EADDR_LEN dup(-1) ;ethernet broadcast address.
ether_addr db EADDR_LEN dup(-1)
ether_byte db ?,?
handle dw ?
bogus_type db 1,2,3,4,5,6,7,8 ;totally bogus type code.
signature db 'PKT DRVR',0
signature_len equ $-signature
no_signature_msg db "No packet driver at that address",'$'
usage_msg db "usage: pktaddr <packet_int_no> [<addr>]",'$'
cant_set_msg db "Can't set our Ethernet address",'$'
bad_addr_msg db "Bad address error",'$'
bad_error_msg db "Unknown error",'$'
eaddr_msg db "My Ethernet address is ",'$'
crlf_msg db CR,LF,'$'
usage_error:
mov dx,offset usage_msg
error:
mov ah,9
int 21h
int 20h
start_1:
mov si,offset phd_dioa+1
cmp byte ptr [si],CR ;end of line?
je usage_error
mov di,offset packet_int_no
call get_number
mov cx,EADDR_LEN
mov di,offset ether_addr
start_2:
push cx
push di
mov di,offset ether_byte
call get_hex
mov al,cl ;remember the number in al.
pop di
pop cx
jc start_3 ;exit if no number at all.
stosb ;store a byte.
cmp byte ptr [si],':' ;skip colons between bytes.
jne start_4
inc si
start_4:
loop start_2
start_3:
mov ah,35h ;get their packet interrupt.
mov al,packet_int_no
int 21h
mov their_isr.offs,bx
mov their_isr.segm,es
lea di,3[bx]
mov si,offset signature
mov cx,signature_len
repe cmpsb
je have_signature
mov dx,offset no_signature_msg
jmp error
have_signature:
push ds
pop es
mov cx,EADDR_LEN
mov si,offset ether_addr
mov di,offset ether_bdcst
repe cmpsb
je get_mode ;no address specified.
mov ah,25 ;set the ethernet address.
mov di,offset ether_addr
mov cx,EADDR_LEN
pushf
cli
call their_isr
jc bad
jmp okay
get_mode:
mov ah,2 ;access all packets.
mov al,1 ;Ethernet class.
mov bx,-1 ;generic type.
mov dl,0 ;generic number.
mov cx,MAX_P_LEN ;use the max type length.
mov si,offset bogus_type
push cs ;es:di -> our receiver.
pop es
mov di,offset our_recv
pushf
cli
call their_isr
jc bad
mov handle,ax
mov ah,6 ;get the ethernet address.
mov di,offset ether_addr
mov cx,EADDR_LEN
mov bx,handle
pushf
cli
call their_isr
jc bad
mov dx,offset eaddr_msg
mov ah,9
int 21h
mov cx,EADDR_LEN
mov si,offset ether_addr
print_addr:
push cx
lodsb
mov cl,' ' ;Don't eliminate leading zeroes.
call byteout
pop cx
cmp cx,1
je print_addr_1
mov al,':'
call chrout
print_addr_1:
loop print_addr
mov dx,offset crlf_msg ;can't depend on DOS to newline for us.
mov ah,9
int 21h
mov ah,3 ;release_type
mov bx,handle
pushf
cli
call their_isr
jc bad
jmp short okay
bad:
cmp dh,CANT_SET
jne bad_1
mov dx,offset cant_set_msg
jmp error
bad_1:
cmp dh,BAD_ADDRESS
jne bad_2
mov dx,offset bad_addr_msg
jmp error
bad_2:
mov dx,offset bad_error_msg
jmp error
okay:
int 20h
our_recv:
or ax,ax ;first or second call?
jne our_recv_1 ;second -- we ignore the packet
push cs
pop es
mov di,offset our_buffer
our_recv_1:
retf
public get_number
get_number:
mov bp,10 ;we default to 10.
jmp short get_number_0
public get_hex
get_hex:
mov bp,16
;get a hex number from [si], skipping leading blanks.
;return cy if there are no digits at all.
;return nc, bx:cx = number, and store cx at [di]
get_number_0:
call skip_blanks
call get_digit ;is there really a number here?
jc get_number_3
or al,al ;Does the number begin with zero?
jne get_number_4 ;no.
mov bp,8 ;yes - they want octal.
get_number_4:
xor cx,cx ;get a hex number.
xor bx,bx
get_number_1:
lodsb
cmp al,'x' ;did they really want hex?
je get_number_5 ;yes.
cmp al,'X' ;did they really want hex?
je get_number_5 ;yes.
call get_digit ;convert a character into an int.
jc get_number_2 ;not a digit (neither hex nor dec).
xor ah,ah
cmp ax,bp ;larger than our base?
jae get_number_2 ;yes.
push ax ;save the new digit.
mov ax,bp ;multiply the low word by ten.
mul cx
mov cx,ax ;keep the low word.
push dx ;save the high word for later.
mov ax,bp
mul bx
mov bx,ax ;we keep only the low word (which is our high word)
pop dx
add bx,ax ;add the high result from earlier.
pop ax ;get the new digit back.
add cx,ax ;add the new digit in.
adc bx,0
jmp get_number_1
get_number_5:
mov bp,16 ;change the base to hex.
jmp get_number_1
get_number_2:
dec si
mov [di],cx ;store the parsed number.
clc
ret
get_number_3:
stc
ret
public skip_blanks
skip_blanks:
lodsb ;skip blanks.
cmp al,' '
je skip_blanks
cmp al,HT
je skip_blanks
dec si
ret
get_digit:
;enter with al = character
;return nc, al=digit, or cy if not a digit.
cmp al,'0' ;decimal digit?
jb get_digit_1 ;no.
cmp al,'9' ;. .?
ja get_digit_2 ;no.
sub al,'0'
clc
ret
get_digit_2:
or al,20h
cmp al,'a' ;hex digit?
jb get_digit_1
cmp al,'f' ;hex digit?
ja get_digit_1
sub al,'a'-10
clc
ret
get_digit_1:
stc
ret
byteout:
mov ah,al
shr al,1
shr al,1
shr al,1
shr al,1
call digout
mov al,ah
digout:
and al,0fh
add al,90h ;binary digit to ascii hex digit.
daa
adc al,40h
daa
cmp al,cl ;leading zero?
je return
mov cl,-1 ;no more leading zeros.
chrout:
push ax ;print the char in al.
xchg al,dl
mov ah,2
int 21h
xchg al,dl
pop ax
return:
ret
our_buffer label byte
code ends
end start